import { keywordCompare } from '@gnlab/utils'
import { mmap, MemSubject, type MemStream } from '@gnlab/utils/rx'
import { type OrderedMap } from 'immutable'
import { useStreams } from '@/lib/utils'
import services from '@/services'
import { searchExternals } from '@/services/contact-types/externals/api'
import { searchInternals } from '@/services/contact-types/internals/api'
import { ContactType, type Contact } from '@/services/contacts'

export const defaultTypes = [ContactType.external, ContactType.internal]

export function useContacts(ownerWxid: string | null, type: ContactType, search: string) {
  const source = useMemo(() => {
    if (type === ContactType.external) {
      return makeExternalSource(ownerWxid, search)
    }
    if (type === ContactType.internal) {
      return makeInternalSource(ownerWxid, search)
    }

    const baseSource: MemStream<OrderedMap<string, Contact>> = services.groups.list
    return baseSource.pipe(
      mmap(all => {
        const filtered = all.filter(contact => {
          if (ownerWxid !== null && contact.ownerWxid !== ownerWxid) return false
          if (
            search &&
            !keywordCompare(search, contact.name) &&
            !keywordCompare(search, contact.remark)
          )
            return false
          return true
        })
        return [...filtered.values()]
      }),
    )
  }, [ownerWxid, type, search])

  const [contacts] = useStreams(source)
  return contacts
}

function makeExternalSource(ownerWxid: string | null, keyword: string) {
  // 有搜索关键词时，调用接口获取客户列表
  // 否则列出当前联系人清单里的客户列表
  if (keyword) {
    const subject = new MemSubject<Contact[]>([])
    const ownerWxids = ownerWxid !== null ? [ownerWxid] : services.qywxs.usableWxids.value
    void searchExternals(ownerWxids, keyword, 1, 10000).then(res => {
      if (res.success) subject.next(res.data)
    })
    return subject.asStream()
  } else {
    return ownerWxid !== null
      ? services.externals.list.pipe(
          mmap(all => [...all.filter(contact => contact.ownerWxid === ownerWxid).values()]),
        )
      : services.externals.list.pipe(mmap(list => [...list.values()]))
  }
}

function makeInternalSource(ownerWxid: string | null, keyword: string) {
  // 有搜索关键词时，调用接口获取员工列表
  // 否则列出当前联系人清单里的员工列表
  if (keyword) {
    const subject = new MemSubject<Contact[]>([])
    const ownerWxids = ownerWxid !== null ? [ownerWxid] : services.qywxs.usableWxids.value
    void searchInternals(ownerWxids, keyword, 1, 10000).then(res => {
      if (res.success) subject.next(res.data)
    })
    return subject.asStream()
  } else {
    return ownerWxid !== null
      ? services.internals.list.pipe(
          mmap(all => [...all.filter(contact => contact.ownerWxid === ownerWxid).values()]),
        )
      : services.internals.list.pipe(mmap(list => [...list.values()]))
  }
}
